#!/usr/bin/env node
const path = require('path')
const shell = require('shelljs')
const program = require('commander')

const { uniConfigLog, helpTip } = require('./utils/log')
const setConfig = require('./utils/setConfig')
const opens = require('./utils/open')
const uploads = require('./utils/uploads')

program
    .version('1.0.17', '-v, --version', '当前版本')
    .option('-m, --minimize', '压缩编译')
    .option('-w, --watch', '监测文件变化，实时编译')
    .helpOption('-h, --help', '查看帮助')
    .option('--view [key]', '查看小程序当前或指定配置信息')
    .option('--set <key>', '设置小程序配置信息为指定项')
    .option('--shell', '执行uniapp运行命令 需要cross-env对应的uniapp一系列变量')
    .option('--map', '查看小程序配置索引')
    .option('--open', '打开小程序编译工具')
    .option('--upload', '上传小程序')
    .parse(process.argv)

const CLI = program.args
const configId = CLI.pop()

// 运行项目路径读取
const PRESET_PATH = process.cwd()

// 当前运行环境变量与运行命令
const NODE_ENV = process.env.NODE_ENV
const UNI_PLATFORM = process.env.UNI_PLATFORM
const EXEC_CODE = getRunPresetExec(NODE_ENV, UNI_PLATFORM, program.watch, program.minimize)

// 可以打开IDE的小程序 打开编译工具执行函数
const OPEN_IDE_FUN = {
    'mp-weixin': opens.openWeixin,
    'mp-alipay': opens.openAlipay
}

// 可以上传代码的小程序 上传代码执行函数
const CODE_UPLOAD_FUN = {
    'mp-weixin': uploads.uploadWeixin,
    'mp-alipay': uploads.uploadAlipay
}

global.PRESET_PATH = PRESET_PATH
global.NODE_ENV = NODE_ENV

if (program.map) {
    setConfig.viewMap()
} else if (program.view) {
    if (program.view === true) {
        setConfig.viewCurrent()
    } else {
        setConfig.viewItem(program.view)
    }
} else if (program.set) {

    const configId = program.set
    setConfig.getCompanyConfig(configId)
        .then(config => {
            setConfig.setCompanyConfig(config)
                .then((config) => {
                    if (config.configData) {
                        uniConfigLog('配置已切换')
                    }
                })
        })
} else if (program.shell) {
    if (!configId) {
        uniConfigLog('请传入配置ID')
        uniConfigLog('或使用 ' + helpTip)
        return
    }

    setConfig.getCompanyConfig(configId)
        .then(config => {
            setConfig.setCompanyConfig(config)
                .then((config) => {
                    if (!config.configData) {
                        uniConfigLog('退出编译')
                        return
                    }
                    if (NODE_ENV !== 'production') {
                        if (config && config.watchDir) { setConfig.watch(path.join(global.PRESET_PATH, config.watchDir), { recursive: true }) }
                        if (config && config.watchDir !== config.configDir) {
                            if (config.configFile) { setConfig.watch(path.join(global.PRESET_PATH, config.configFile)) }
                        }
                        if (config && config.extend) {
                            for (let k in config.extend) {
                                const watchFile = config.extend[k].watchFile
                                const options = config.extend[k].watchOptions
                                if (watchFile) {
                                    setConfig.watch(path.join(global.PRESET_PATH, watchFile), options)
                                }
                            }
                        }
                        console.log('\n')
                    }
                    setTimeout(() => {
                        uniConfigLog('配置结束，准备编译 ...')
                        console.log('\n')
                        run(config)
                    }, 2000)
                })
        })
}

function run (config = {}) {
    let openIde
    if (OPEN_IDE_FUN[UNI_PLATFORM]) {
        openIde = OPEN_IDE_FUN[UNI_PLATFORM]
    }
    // openIde(config, NODE_ENV, UNI_PLATFORM, PRESET_PATH, false)
    // return
    if (program.open && openIde && NODE_ENV !== 'production') {
        openIde(config, NODE_ENV, UNI_PLATFORM, PRESET_PATH, true)
        exec()
    } else {
        exec(config)
    }
}

function exec (config) {
    console.log(EXEC_CODE)
    console.log('\n')

    // 打开完毕后, 运行编译工具
    shell.cd(global.PRESET_PATH)
    shell.exec(EXEC_CODE, (code) => {
        if (code === 0 && program.upload === true) {
            let codeUpload
            if (CODE_UPLOAD_FUN[UNI_PLATFORM]) {
                codeUpload = CODE_UPLOAD_FUN[UNI_PLATFORM]
                if (codeUpload) {
                    console.log('\n')
                    uniConfigLog('即将上传代码 ...')
                    codeUpload(config, NODE_ENV, UNI_PLATFORM, PRESET_PATH)
                        .then((code) => {
                            console.log(code)
                        })
                }
            }
        } else if (code !== 0) {
            if (opens.cancelOpen) {
                opens.cancelOpen()
            }
            shell.exit()
        }
    })
}

function getRunPresetExec (env = 'development', type = 'h5', isWatch = false, isMinimize = false) {
    const minimize = isMinimize ? '--minimize' : ''
    const watch = isWatch ? '--watch' : ''
    const command = type === 'h5' && env !=='production' ? 'uni-serve' : 'uni-build'
    return `cross-env NODE_ENV=${env} UNI_PLATFORM=${type} vue-cli-service ${command} ${watch} ${minimize} --color=always`
}
